package com.dxtan90.judge;

import com.dxtan90.bean.Action;
import com.dxtan90.bean.Position;
import com.dxtan90.order.RobotOrder;
import com.dxtan90.order.impl.*;
import com.dxtan90.utils.ConfigUtils;
import com.dxtan90.utils.RobotUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: shijunhao
 * @date: 2021/12/1 18:03
 * @description: 解决在一张图片里面寻找对应图片的位置问题
 */
public class PositionJudge {

    private static Map<String, RobotOrder> order = new HashMap<>();

    static {
        order.put("MOUSE1CLICK",new Mouse1ClickOrder());
        order.put("MOUSE1DOUBLECLICK",new Mouse1DoubleClickOrder());
        order.put("MOUSE1PRESS",new Mouse1PressOrder());
        order.put("MOUSE1RELEASE",new Mouse1ReleaseOrder());
        order.put("MOUSE3CLICK",new Mouse3ClickOrder());
        order.put("MOUSEMOVE",new MouseMoveOrder());
        order.put("MOUSEWHEEL",new MouseWheelOrder());
        order.put("DELAY",new DelayOrder());
        order.put("KEYCLICK",new KeyClickOrder());
        order.put("KEYPRESS",new KeyPressOrder());
        order.put("KEYRELEASE",new KeyReleaseOrder());
    }

    /**
     * @param oriImg: 原图
     * @param tarImg: 所寻找的图片
     * @return: com.dxtan90.bean.Position 位置
     * @author: shijunhao
     * @date: 2021/12/1 18:09
     * @description: 查找目标位置
     */
    public Position findPosition(BufferedImage oriImg, BufferedImage tarImg, double sameLine) {
        PictureSameJudge pictureSameJudge = new PictureSameJudge();
        int tarWidth = tarImg.getWidth();
        int tarHeight = tarImg.getHeight();

        if (oriImg.getHeight() < tarHeight || oriImg.getWidth() < tarWidth) {
            return new Position(-1, -1);
        }

        //四点像素
        int ltc = tarImg.getRGB(0, 0);
        int rtc = tarImg.getRGB(tarWidth - 1, 0);
        int lbc = tarImg.getRGB(0, tarHeight - 1);
        int rbc = tarImg.getRGB(tarWidth - 1, tarHeight - 1);

        for (int i = 0; i <= oriImg.getWidth() - tarWidth; i++) {
            for (int j = 0; j <= oriImg.getHeight() - tarHeight; j++) {
                //四点相同进入相同图片判断
                if (oriImg.getRGB(i, j) == ltc
                        && oriImg.getRGB(i + tarWidth - 1, j) == rtc
                        && oriImg.getRGB(i, j + tarHeight - 1) == lbc
                        && oriImg.getRGB(i + tarWidth - 1, j + tarHeight - 1) == rbc) {
                    //临时对比图
                    BufferedImage tmpImg = oriImg.getSubimage(i, j, tarImg.getWidth(), tarImg.getHeight());
                    //输出对比相似度
                    double similarity = pictureSameJudge.getSimilarity(tmpImg, tarImg);
                    if (similarity >= sameLine) {
                        int centerX = i + tarWidth / 2;
                        int centerY = j + tarHeight / 2;
                        return new Position(i, j, centerX, centerY);
                    }
                }
            }
        }
        return new Position(-1, -1);
    }

    /**
     * @param action: 操作信息
     * @return: boolean
     * @author: shijunhao
     * @date: 2021/12/1 23:10
     * @description: 处理对应操作
     */
    public boolean doAction(Action action){
        if(action.getImgFind()){
            BufferedImage tarImg = null;
            try {
                tarImg = ImageIO.read(new File(action.getTarImgPath()));
                BufferedImage screen = RobotUtils.getRobot()
                        .createScreenCapture(new Rectangle(0, 0, ConfigUtils.getDimension().width, ConfigUtils.getDimension().height));
                Position position = findPosition(screen, tarImg, ConfigUtils.getConfig().getSameLine());
                if(position.getUseful()){
                    action.setPosition(position);
                    order.get(action.getOperation().toUpperCase()).doOperation(position);
                    System.out.println("操作成功: "+action);
                    return true;
                }
            } catch (IOException e) {
                System.out.println("对应操作图标不存在！！！");
                e.printStackTrace();
            }
        }else{
            order.get(action.getOperation().toUpperCase()).doOperation(action.getPosition());
            System.out.println("操作成功: "+action);
            return true;
        }
        return false;
    }

    /**
     * @return: com.dxtan90.bean.Action 首流程
     * @author: shijunhao
     * @date: 2021/12/1 22:54
     * @description: 读取流程链条
     */
    public Action getActions(){
        String path = ConfigUtils.getConfig().getOperationFilePath();
        File file = new File(path);
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        Action head = null;
        try {
            fileReader  = new FileReader(file);
            bufferedReader = new BufferedReader(fileReader);
            String line;
            Action next = null;
            //读取流程链
            while((line = bufferedReader.readLine()) != null && !"".equals(line.trim())){
                Action action = analysisOrder(line);
                if(head == null){
                    head = action;
                    next = action;
                }else{
                    next = next.nextAction(action);
                }
            }
            return head;
        } catch (IOException e) {
            System.out.println("读取文件失败");
            e.printStackTrace();
        }finally {
            try {
                if(bufferedReader != null)
                    bufferedReader.close();
                if(fileReader != null)
                    fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return head;
    }

    /**
     * @param order: 单条指令
     * @return: com.dxtan90.bean.Action
     * @author: shijunhao
     * @date: 2021/12/2 15:41
     * @description: 解析每条指令操作
     */
    private Action analysisOrder(String order){
        Action action = new Action();
        String[] orders = order.split(" ");
        if(orders.length != 3)
            throw new RuntimeException("请按照标准填写指令");
        action.setOperation(orders[0]);
        action.setImgFind(Boolean.valueOf(orders[1]));
        //如果不是搜图，则直接获取坐标信息
        if(!action.getImgFind())
            action.setPosition(PositionJudge.order.get(action.getOperation().toUpperCase()).analysisData(orders[2]));
        //否则获取图片文件地址
        else action.setTarImgPath(orders[2]);
        return action;
    }
}
